﻿using System;
using Autodesk.Revit.DB;

namespace HYFloorPipeModule
{
	public class PointPair
	{
		public PointPair()
		{
			this.m_bIn = false;
			this.m_bIsLoopFirst = false;
		}

		public PointPair(PointPair src)
		{
			this.m_ptFirst = src.m_ptFirst;
			this.m_ptSecond = src.m_ptSecond;
			this.m_bIn = src.m_bIn;
			this.m_bIsLoopFirst = src.m_bIsLoopFirst;
		}

		public PointPair(XYZ f, XYZ s, bool bIn, bool bIsLoopFirst = false)
		{
			this.m_ptFirst = f;
			this.m_ptSecond = s;
			this.m_bIn = bIn;
			this.m_bIsLoopFirst = bIsLoopFirst;
		}

		public XYZ First
		{
			get
			{
				return this.m_ptFirst;
			}
			set
			{
				this.m_ptFirst = value;
			}
		}

		public XYZ Second
		{
			get
			{
				return this.m_ptSecond;
			}
			set
			{
				this.m_ptSecond = value;
			}
		}

		public bool IsIn
		{
			get
			{
				return this.m_bIn;
			}
			set
			{
				this.m_bIn = value;
			}
		}

		public bool IsLoopFirst
		{
			get
			{
				return this.m_bIsLoopFirst;
			}
		}

		public void Reset(XYZ f, XYZ s, bool bIn = false, bool bIsLoopFirst = false)
		{
			this.m_ptFirst = f;
			this.m_ptSecond = s;
			this.m_bIn = bIn;
			this.m_bIsLoopFirst = bIsLoopFirst;
		}

		public void Offset(XYZ v)
		{
			this.m_ptFirst += v;
			this.m_ptSecond += v;
		}

		public void Retract(double dF, double dS)
		{
			XYZ xyz = this.AsVector();
			xyz = xyz.Normalize();
			this.m_ptFirst += xyz * dF;
			this.m_ptSecond -= xyz * dS;
		}

		public double GetLength()
		{
			return this.m_ptFirst.DistanceTo(this.m_ptSecond);
		}

		public XYZ AsVector()
		{
			return this.m_ptSecond - this.m_ptFirst;
		}

		public void DoExchange()
		{
			XYZ ptFirst = this.m_ptFirst;
			this.m_ptFirst = this.m_ptSecond;
			this.m_ptSecond = ptFirst;
		}

		public Line CreateLine()
		{
			if (!this.m_ptFirst.IsAlmostEqualTo(this.m_ptSecond))
			{
				return Line.CreateBound(this.m_ptFirst, this.m_ptSecond);
			}
			return null;
		}

		public double DistanceTo(PointPair ppOther)
		{
			Line line = Line.CreateBound(this.m_ptFirst, this.m_ptSecond);
			Line line2 = Line.CreateBound(ppOther.First, ppOther.Second);
			if (line.Direction.Normalize().IsAlmostEqualTo(line2.Direction.Normalize()) || line.Direction.Normalize().IsAlmostEqualTo(-line2.Direction.Normalize()))
			{
				line2.MakeUnbound();
				XYZ xyzpoint = line2.Project(this.m_ptFirst).XYZPoint;
				return this.m_ptFirst.DistanceTo(xyzpoint);
			}
			return 0.0;
		}

		public double DistanceTo(XYZ point)
		{
			Line line = Line.CreateBound(this.m_ptFirst, this.m_ptSecond);
			line.MakeUnbound();
			return point.DistanceTo(line.Project(point).XYZPoint);
		}

		public XYZ GetProject(XYZ point)
		{
			Line line = this.CreateLine();
			line.MakeUnbound();
			return line.Project(point).XYZPoint;
		}

		public override string ToString()
		{
			return "First Point:" + this.m_ptFirst.ToString() + "\nSecond Point:" + this.m_ptSecond.ToString();
		}

		private XYZ m_ptFirst;

		private XYZ m_ptSecond;

		private bool m_bIn;

		private bool m_bIsLoopFirst;
	}
}
